当DP遇见Py(二) -- 策略模式

目录
  1. 定义
  2. 类图
  3. 类型:行为型
  4. 实例
    1. C++ 实现
    2. Python 实现
    3. Pythonic 实现
  5. Tips:

定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

类图

类型:行为型

实例

商场收银软件,需要根据不同的销售策略方式进行收费

C++ 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <cmath>
#include <string>
using namespace std;

class CashSuper
{
public:
virtual double acceptMoney(double money)=0;
};

class CashNormal:public CashSuper
{
public:
double acceptMoney(double money)
{

return money;
}
};

class CashRebate:public CashSuper
{
private:
double discount;
public:
CashRebate(double dis)
{
discount = dis;
}
double acceptMoney(double money)
{

return money * discount;
}
};


class CashReturn:public CashSuper
{
private:
double moneyCondition;
double moneyReturn;
public:
CashReturn(double mc,double mr)
{
moneyCondition = mc;
moneyReturn = mr;
}
double acceptMoney(double money)
{

double result = money;
if(money >= moneyCondition)
{
result = money - floor(money / moneyCondition) * moneyReturn;
}
return result;
}
};

class CashContext
{
private:
CashSuper *cs;
public:
CashContext(CashSuper *cs)
{
this->cs = cs;
}
double getResult(double money)
{

return cs->acceptMoney(money);
}
};

int main()
{

CashSuper *cs;
CashContext *cc;
double money;

money = 1000;
cs = new CashRebate(0.8);
cc = new CashContext(cs);
cout << cc->getResult(money) << endl;

money = 1000;
cs = new CashNormal();
cc = new CashContext(cs);
cout << cc->getResult(money) << endl;


return 0;
}

Python 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from math import floor

class CashSuper(object):
def acceptMoney(self, money):
return 0

class CashNormal(CashSuper):
def acceptMoney(self, money):
return money

class CashRebate(CashSuper):
def __init__(self, discount):
self._discount = discount

def acceptMoney(self, money):
return money * self._discount

class CashReturn(CashSuper):
def __init__(self, mc, mr):
self._moneyCondition = mc
self._moneyReturn = mr

def acceptMoney(self, money):
if money >= self._moneyCondition:
return money - floor(money / self._moneyCondition) * self._moneyReturn
else:
return money

class CashContext:
def __init__(self, cs):
self._cs = cs

def getResult(self, money):
return self._cs.acceptMoney(money)

if __name__ == '__main__':
money = 1000

cc = CashContext(CashRebate(0.8))
print cc.getResult(money)

cc = CashContext(CashNormal())
print cc.getResult(money)

Pythonic 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class CashContext:
def __init__(self, cs):
self._cs = cs

def getResult(self, money):
return self._cs(money)

def cashNormal():
def accpetMoney(money):
return money
return accpetMoney

def cashRebate(discount):
def accpetMoney(money):
return money * discount
return accpetMoney

def cashReturn(mc, mr):
def accpetMoney(money):
if money >= mc:
return money - floor(money / mc) * mr
else:
return money
return accpetMoney


if __name__ == '__main__':
money = 1000

cc = CashContext(cashNormal())
print cc.getResult(money)

cc = CashContext(cashRebate(0.8))
print cc.getResult(money)

cc = CashContext(cashReturn(300, 100))
print cc.getResult(money)

Tips:

  • 在大多数的编程语言中,策略模式实现是这样的: 首先创建一个基础策略(通过接口或抽象类),然后创建若干子类继承这个基础策略。然而,Python支持高阶函数,可以使我们仅仅使用一个类,并把不同的函数注入该类的对象中来实现策略模式。详见:Pythonic 实现
  • 高阶函数(higher-order functions)。所谓高阶函数,就是操作函数的函数,一个函数可以接受另一个函数作为参数,也可以把一个函数作为结果来返回。
  • 闭包(Closures)。在cashNormalcashReturn等函数中定义了一个函数accpetMoney,我们说accpetMoneycashNormalcashReturn等的内部函数。在accpetMoney的局部作用域中可以直接访问cashReturn局部作用域中定义的mcmr变量。简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包。
  • 函数式编程(Functional programming)。高阶函数和闭包都是函数式编程的特点。因此Python支持函数式编程。关于Python如何支持函数式编程值得深入研究,有兴趣的同学可以查阅相关资料。

评论